/**
 * 
 */
package gemini.pollux.ui.server.service;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dozer.DozerBeanMapper;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

/**
 * 
 *
 */
public abstract class AbstractService implements InitializingBean {
    
    private final Log logger = LogFactory.getLog(getClass());
    
    private DozerBeanMapper dozerBeanMapper;
    
    private DozerBeanMapper excludeFieldsDozerBeanMapper;
    
    public void setDozerBeanMapper(final DozerBeanMapper dozerBeanMapper) {
        this.dozerBeanMapper = dozerBeanMapper;
    }
    
    @SuppressWarnings("unchecked")
    protected <T> T duplicate(final T source) {
        if (source == null) {
            return null;
        }
        long start = System.currentTimeMillis();
        
        T result = dozerBeanMapper.map(source, (Class<T>) source.getClass());
        if (logger.isTraceEnabled()) {
            logger.trace(" - StopWatch duplicating class " + source.getClass().getSimpleName() + " in: "
                    + (System.currentTimeMillis() - start) + "ms");
        }
        return result;
    }
    
    protected <T> ArrayList<T> duplicate(final List<T> source) {
        if (source == null) {
            return null;
        }
        long start = System.currentTimeMillis();

        ArrayList<T> result = new ArrayList<T>();
        for (T src : source) {
            result.add(duplicateExcludeFields(src));
        }
        
        if (logger.isTraceEnabled()) {
            if ((source.size() > 0) && (source.get(0) != null)) {
                logger.trace(" - StopWatch duplicating list of class "
                        + source.get(0).getClass().getSimpleName() + " in: "
                        + (System.currentTimeMillis() - start) + "ms");
            }
        }

        return result;
    }

    @SuppressWarnings("unchecked")
    protected <T> T duplicateExcludeFields(final T source) {
        if (source == null) {
            return null;
        }
        return excludeFieldsDozerBeanMapper.map(source, (Class<T>) source.getClass());
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Assert.notNull(dozerBeanMapper, 
                "'dozerBeanMapper' is required for this RPC service");
    }
    
    public DozerBeanMapper getExcludeFieldsDozerBeanMapper() {
        return excludeFieldsDozerBeanMapper;
    }

    public void setExcludeFieldsDozerBeanMapper(final DozerBeanMapper excludeFieldsDozerBeanMapper) {
        this.excludeFieldsDozerBeanMapper = excludeFieldsDozerBeanMapper;
    }

}
